home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / smail-3.1.28 / src / direct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-11  |  31.4 KB  |  1,134 lines

  1. /* @(#)src/direct.c    1.5 7/11/92 11:48:20 */
  2.  
  3. /*
  4.  *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  5.  *    Copyright (C) 1992  Ronald S. Karr
  6.  * 
  7.  * See the file COPYING, distributed with smail, for restriction
  8.  * and warranty information.
  9.  */
  10.  
  11. /*
  12.  * direct.c:
  13.  *    resolve local form addresses to more addresses or to transports
  14.  *
  15.  *    external functions: direct_local_addrs, verify_local_addrs,
  16.  *                cache_directors, finish_directors,
  17.  *                director_user_info, find_director,
  18.  *                find_direct_driver, read_director_file.
  19.  */
  20. #include <stdio.h>
  21. #include <pwd.h>
  22. #include <grp.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include "defs.h"
  26. #include "smail.h"
  27. #include "direct.h"
  28. #include "transport.h"
  29. #include "log.h"
  30. #include "addr.h"
  31. #include "main.h"
  32. #include "dys.h"
  33. #include "exitcodes.h"
  34. #include "smailconf.h"
  35. #ifndef DEPEND
  36. # include "debug.h"
  37. # include "extern.h"
  38. # include "error.h"
  39. #endif
  40.  
  41. /* enums local to this file */
  42. enum local_form {
  43.     FILE_FORM,                /* filename address */
  44.     PIPE_FORM,                /* shell-command address */
  45.     INCLUDE_FORM,            /* mailing list address */
  46.     OTHER_FORM,                /* any other address form */
  47. };
  48. enum other_form_op {
  49.     SEND_TO_NEXT,            /* send addr to next director */
  50.     DROP_ADDRESS,            /* ignore addr */
  51.     ADDRESS_OKAY,            /* reparse address */
  52. };
  53.  
  54. /* variables exported from this file */
  55. int cached_directors = FALSE;        /* TRUE if cache_directors() called */
  56.  
  57. /* functions local to this file */
  58. static void implicit_redirect();
  59. static enum other_form_op finish_direct_other_form();
  60. static void finish_direct_special_form();
  61. static void cache_director_data();
  62. static void premunge_local_addrs();
  63. static enum local_form addr_type();
  64. static int verify_special();
  65. static char *director_driv_function();
  66.  
  67.  
  68. /*
  69.  * direct_local_addrs - produce finished and expanded addrs from local addrs
  70.  *
  71.  * this is called from resolve_addr_list to run local-form addresses
  72.  * through the directors to completely resolve addr structures and
  73.  * to transform them into a new list of addr structures to resolve.
  74.  */
  75. void
  76. direct_local_addrs(in, out, retry, defer, fail)
  77.     struct addr *in;            /* input local-form addrs */
  78.     struct addr **out;            /* output resolved addrs */
  79.     struct addr **retry;        /* addr structures to reparse */
  80.     struct addr **defer;        /* addrs to defer to a later time */
  81.     struct addr **fail;            /* unresolvable addrs */
  82. {
  83.     struct director *dp;        /* temp for stepping thru directors */
  84.     struct addr *cur;            /* temp for stepping through addrs */
  85.     struct addr *newaddrs;        /* new addrs from a director */
  86.     struct addr *includes;        /* mailing list addrs */
  87.     struct addr *next;            /* next value for cur */
  88.     DEBUG(DBG_DIRECT_HI, "direct_local_addrs called\n");
  89.  
  90.     /* do any munging of the addr structures required before directing */
  91.     premunge_local_addrs(in);
  92.  
  93.     /*
  94.      * call each director in turn, where each director
  95.      * produces an output list a list of addrs it could
  96.      * not resolve, and a list of addrs it resolved to
  97.      * a list.  The actual return value is the list it
  98.      * could not resolve.
  99.      */
  100.     *retry = NULL;
  101.     includes = NULL;
  102.     while (in) {
  103.     /*
  104.      * directors are organized as subsections with the subsection
  105.      * data being the director structures.
  106.      */
  107.     for (dp = directors; in && dp; dp = dp->succ) {
  108.         /* look up the director driver by name */
  109.         struct direct_driver *driver = find_direct_driver(dp->driver);
  110.  
  111.         if (driver == NULL) {
  112.         /*
  113.          * ERR_107 - director driver not found
  114.          *
  115.          * DESCRIPTION
  116.          *      A director driver was not found.
  117.          *
  118.          * ACTIONS
  119.          *      Defer all remaining input addresses with
  120.          *      configuration errors.  Since it is not known if this
  121.          *      director would have matched any addresses, we cannot
  122.          *      pass the addresses on to the next director.  Thus,
  123.          *      we must defer all addresses not matched by a
  124.          *      previous director.
  125.          *
  126.          * RESOLUTION
  127.          *      The postmaster must check the director and transport
  128.          *      configurations before delivery can be performed.
  129.          */
  130.         insert_addr_list(in,
  131.                  defer,
  132.                  note_error(ERR_CONFERR|ERR_107,
  133.                         xprintf(
  134.                      "director %s: driver %s driver not found",
  135.                             dp->name,
  136.                             dp->driver)));
  137.         exitvalue = EX_DATAERR;
  138.         return;
  139.         }
  140.         /* initialize list of new addrs found in this pass */
  141.         newaddrs = NULL;
  142.  
  143.         /* call the driver */
  144.         in = (*driver->driver)(dp, in, out, &newaddrs, defer, fail);
  145.  
  146.         /* step through newaddrs to verify them */
  147.         for (cur = newaddrs; cur; cur = next) {
  148.         enum local_form form = addr_type(cur->work_addr);
  149.  
  150.         next = cur->succ;    /* note which addr to examine next */
  151.  
  152.         /*
  153.          * read in cache data in the director structure, if this
  154.          * has not yet been done.
  155.          */
  156.         if (! (dp->flags & CACHED_DIRECTOR) ) {
  157.             cache_director_data(dp);
  158.         }
  159.  
  160.         /* setup the uid, gid and home directories for the addr */
  161.         if (dp->default_user) {
  162.             if (cur->uid == BOGUS_USER) {
  163.             cur->uid = dp->default_uid;
  164.             }
  165.             if (cur->gid == BOGUS_GROUP) {
  166.             cur->gid = dp->default_gid;
  167.             }
  168.         }
  169.         if (dp->default_home && cur->home == NULL) {
  170.             cur->home = dp->x_default_home;
  171.         }
  172.         if (dp->set_user) {
  173.             cur->uid = dp->set_uid;
  174.             cur->gid = dp->set_gid;
  175.         }
  176.         if (dp->set_home) {
  177.             cur->home = dp->x_set_home;
  178.         }
  179.  
  180.         if (dp->flags & CAUTION_DIRECTOR) {
  181.             /* be cautious on all addrs from this director */
  182.             cur->flags |= ADDR_CAUTION;
  183.         }
  184.  
  185.         if (form == OTHER_FORM) {
  186.             switch (finish_direct_other_form(dp, cur)) {
  187.             case SEND_TO_NEXT:
  188.             /* matched the parent addr, send to next director */
  189.             cur->succ = in;
  190.             in = cur;
  191.             break;
  192.             case DROP_ADDRESS:
  193.             /* matched the sender, drop the address */
  194.             break;
  195.             case ADDRESS_OKAY:
  196.             /* address is okay, put back on the input */
  197.             cur->succ = *retry;
  198.             *retry = cur;
  199.             break;
  200.             }
  201.         } else {
  202.             finish_direct_special_form(cur, dp, form,
  203.                            retry, out, defer, fail,
  204.                            &includes);
  205.         }
  206.         }
  207.     }
  208.  
  209.     /*
  210.      * log addrs which were not directed anywhere
  211.      */
  212.     for (; in; in = next) {
  213.         next = in->succ;
  214.  
  215. #ifndef    NO_PETER_HONEYMAN
  216.         /*
  217.          * Peter Honeyman once told us that he prefered flat address
  218.          * spaces.  You can help to further his cause by not defining
  219.          * NO_PETER_HONEYMAN.  If this is not defined then all mail
  220.          * destined to the user `honey' or 'peter.honeyman' will be
  221.          * sent to Peter Honeyman's mail address.  When all machines
  222.          * in the world use smail and don't define this, no user need
  223.          * ever know Peter's address.
  224.          */
  225.         if (EQIC(in->remainder, "honey") ||
  226.         EQIC(in->remainder, "peter.honeyman") ||
  227.         EQIC(in->remainder, "peter honeyman"))
  228.         {
  229.         implicit_redirect(in, retry, "honey@citi.umich.edu");
  230.         } else
  231. #endif    /* NO_PETER_HONEYMAN */
  232.         if (EQIC(in->remainder, "MAILER-DAEMON")) {
  233.         implicit_redirect(in, retry, "Postmaster");
  234.         } else if (EQIC(in->remainder, "Postmaster")) {
  235.         implicit_redirect(in, retry, postmaster_address);
  236.         } else {
  237.         /* no director found the user, fail the address */
  238.         exitvalue = EX_NOUSER;    /* also set exit status */
  239.         /*
  240.          * ERR_100 - unknown user
  241.          *
  242.          * DESCRIPTION
  243.          *    The remainder structure in this addr structure was
  244.          *      not matched by any of the directors.
  245.          *
  246.          * ACTIONS
  247.          *      Send a message to the owner of the address, or to
  248.          *      the sender if there is no owner.
  249.          *
  250.          * RESOLUTION
  251.          *      A list owner should check through the list that he
  252.          *      or she owns.  A sender may wish to send mail to the
  253.          *      postmaster of the machine asking about login names
  254.          *      for a particular user.
  255.          */
  256.         in->error = note_error(ERR_NSOWNER|ERR_100, "unknown user");
  257.         in->succ = *fail;
  258.         *fail = in;
  259.         }
  260.     }
  261.  
  262.     /*
  263.      * copy any mailing list addrs back to the input
  264.      * so they can be run back through the directors.
  265.      */
  266.     in = includes;
  267.     includes = NULL;
  268.     }
  269. }
  270.  
  271.  
  272. /*
  273.  * verify_local_addrs - perform quick verify of local addresses
  274.  *
  275.  * form a list of okay (verified) addrs, plus deferred (not currently
  276.  * determinable) addrs and failed (not deliverable) addrs.
  277.  */
  278. void
  279. verify_local_addrs(in, okay, defer, fail)
  280.     struct addr *in;            /* input local addr list */
  281.     struct addr **okay;            /* output list of verified addrs */
  282.     struct addr **defer;        /* temporariliy unverifiable addrs */
  283.     struct addr **fail;            /* unverified addrs */
  284. {
  285.     struct director *dp;        /* temp for stepping thru directors */
  286.     register struct addr *cur;        /* temp for stepping through addrs */
  287.     struct addr *next;            /* next value for cur */
  288.  
  289.     DEBUG(DBG_ROUTE_HI, "verify_local_addrs called\n");
  290.  
  291.     /* do any munging of the addr structures required before directing */
  292.     premunge_local_addrs(in);
  293.  
  294.     /*
  295.      * give the complete input list to each director in turn.
  296.      */
  297.     for (dp = directors; in && dp; dp = dp->succ) {
  298.     /* look up the director driver by name */
  299.     struct direct_driver *driver = find_direct_driver(dp->driver);
  300.     struct addr *retry;        /* set of addrs for next director */
  301.  
  302.     if (driver == NULL) {
  303.         /*
  304.          * ERR_107 - director driver not found
  305.          *
  306.          * DESCRIPTION
  307.          *      A driver name was not found in the table of director
  308.          *      drivers.
  309.          *
  310.          * ACTIONS
  311.          *      Defer all remaining input addresses with configuration
  312.          *      errors.  Since it is not known if this director would
  313.          *      have matched any addresses, we cannot pass the addresses
  314.          *      on to the next director.  Thus, we must defer all
  315.          *      addresses not matched by a previous director.
  316.          *
  317.          * RESOLUTION
  318.          *      The postmaster must check the director and transport
  319.          *      configurations before delivery can be performed.
  320.          */
  321.         insert_addr_list(in,
  322.                  defer,
  323.                  note_error(ERR_CONFERR|ERR_107,
  324.                     xprintf(
  325.                      "director %s: driver %s driver not found",
  326.                         dp->name,
  327.                         dp->driver)));
  328.         return;
  329.     }
  330.  
  331.     /* call the driver */
  332.     retry = NULL;
  333.     (*driver->verify)(dp, in, &retry, okay, defer, fail);
  334.     in = retry;
  335.     }
  336.  
  337.     for (cur = in; cur; cur = next) {
  338.     next = cur->succ;
  339.  
  340. #ifndef    NO_PETER_HONEYMAN
  341.     /*
  342.      * Peter Honeyman once told us that he prefered flat address
  343.      * spaces.  You can help to further his cause by not defining
  344.      * NO_PETER_HONEYMAN.  If this is not defined then all mail
  345.      * destined to the user `honey' or 'peter.honeyman' will be
  346.      * sent to Peter Honeyman's mail address.  When all machines
  347.      * in the world use smail and don't define this, no user need
  348.      * ever know Peter's address.
  349.      */
  350.     if (EQIC(in->remainder, "honey") ||
  351.         EQIC(in->remainder, "peter.honeyman") ||
  352.         EQIC(in->remainder, "peter honeyman"))
  353.     {
  354.         cur->succ = *okay;
  355.         *okay = cur;
  356.     } else
  357. #endif    /* NO_PETER_HONEYMAN */
  358.     {
  359.         /* no director found the user, fail the address */
  360.         exitvalue = EX_NOUSER;    /* also set exit status */
  361.         /*
  362.          * ERR_100 - unknown user
  363.          *
  364.          * DESCRIPTION
  365.          *      The remainder structure in this addr structure was not
  366.          *      matched by any of the directors.
  367.          *
  368.          * ACTIONS
  369.          *      Send a message to the owner of the address, or to the
  370.          *      sender if there is no owner.
  371.          *
  372.          * RESOLUTION
  373.          *      A list owner should check through the list that he or
  374.          *      she owns.  A sender may wish to send mail to the
  375.          *      postmaster of the machine asking about login names for a
  376.          *      particular user.
  377.          */
  378.         cur->error = note_error(ERR_NSOWNER|ERR_100, "unknown user");
  379.         cur->succ = *fail;
  380.         *fail = cur;
  381.     }
  382.     }
  383. }
  384.  
  385.  
  386. /*
  387.  * cache_directors - call cache entrypoints for all directors
  388.  *
  389.  * cache information used by director drivers.  This can be called
  390.  * when it is determined that there will be an attempt to deliver more
  391.  * than one mail message, to increase the overall efficiency of the
  392.  * mailer.
  393.  *
  394.  * Daemons can call this periodically to recache stale data.
  395.  */
  396. void
  397. cache_directors()
  398. {
  399.     struct director *dp;        /* temp for stepping thru directors */
  400.     struct direct_driver *driver;
  401.  
  402.     for (dp = directors; dp; dp = dp->succ) {
  403.     driver = find_direct_driver(dp->driver);
  404.     if (driver && driver->cache) {
  405.         (*driver->cache)(dp);
  406.     }
  407.     }
  408.     cached_directors = TRUE;
  409. }
  410.  
  411. #ifdef notyet
  412. /*
  413.  * finish_directors - free resources used by all directors
  414.  *
  415.  * free information that was cached by directors or used by directors
  416.  * in the process of resolving local addresses.  Directors can cache
  417.  * data for efficiency, or can maintain state between invocations.
  418.  * This function is called when directors will no longer be needed,
  419.  * allowing directors to free any resources that they were using that
  420.  * will no longer be needed.  For example, it is a good idea for
  421.  * directors to close any files that they opened, as file descriptors
  422.  * are a precious resource in some machines.
  423.  */
  424. void
  425. finish_directors()
  426. {
  427.     struct directors *dp;        /* temp for stepping thru directors */
  428.     struct direct_driver *driver;
  429.  
  430.     for (dp = directors; dp; dp = dp->succ) {
  431.     driver = find_direct_driver(dp->driver);
  432.     if (driver && driver->finish) {
  433.         (*driver->finish)(dp);
  434.     }
  435.     }
  436.     cached_directors = FALSE;
  437. }
  438. #endif
  439.  
  440.  
  441. /*
  442.  * implicit_redirect - an implicit director to redirect to the given address
  443.  */
  444. static void
  445. implicit_redirect(match, retry, in_addr)
  446.     struct addr *match;            /* addr structure to direct */
  447.     struct addr **retry;        /* attach new addr to this list */
  448.     char *in_addr;            /* the text for the new address */
  449. {
  450.     struct addr *new = alloc_addr();
  451.     new->in_addr = COPY_STRING(in_addr);
  452.     new->work_addr = COPY_STRING(in_addr);
  453.     new->succ = *retry;
  454.     *retry = new;
  455.     DEBUG3(DBG_DIRECT_LO,
  456.        "smail implicity matched %s\n    directed %s --> %s\n",
  457.        match->in_addr, match->in_addr, in_addr);
  458. }
  459.  
  460. /*
  461.  * finish_direct_other_form - finish directing a simple addr
  462.  *
  463.  * return SEND_TO_NEXT if this addr matches the parent addr and should
  464.  *   thus be sent to the next director rather than being put on the
  465.  *   list of new addrs.
  466.  * return DROP_ADDRESS if this addr is in local form and matches the
  467.  *   sender and should thus be ignored.  This value is not returned if
  468.  *   the `sender_okay' attribute is set for the director, or if the
  469.  *   me_too flag was set in the invocation arguments.
  470.  * return ADDRESS_OKAY if the addr should be put on the list of
  471.  *   addresses to be reparsed.
  472.  *
  473.  * XXX - this may change the addr structure as a side effect, so watch out.
  474.  */
  475. static enum other_form_op
  476. finish_direct_other_form(dp, addr)
  477.     struct director *dp;        /* director which returned addr */
  478.     struct addr *addr;            /* addr struct from director */
  479. {
  480.     int parseflags;
  481.  
  482.     /* not an address form we need to be worried about */
  483.     if (EQIC(addr->work_addr, addr->parent->remainder) ||
  484.     (addr->work_addr[0] == '\\' &&
  485.      EQIC(addr->work_addr + 1, addr->parent->remainder)))
  486.     {
  487.     /* for the form \parent-addr drop the \ */
  488.     if (addr->work_addr[0] == '\\') {
  489.         (void) strcpy(addr->work_addr, addr->work_addr + 1);
  490.     }
  491.  
  492.     /*
  493.      * new addr same as input addr, send to
  494.      * the next director.  E.g., foo aliased
  495.      * to foo.
  496.      */
  497.     DEBUG2(DBG_DIRECT_LO,
  498.            "    directed %s --> %s ... matched, pass to next director\n",
  499.            addr->parent->remainder,
  500.            addr->work_addr);
  501.     addr->remainder = addr->work_addr;
  502.     return SEND_TO_NEXT;
  503.     } else {
  504.     /*
  505.      * XXX - reparse the address looking for references
  506.      *     to the the localhost with a remainder equal
  507.      *     to the parent address.  This allows the use
  508.      *     of username@localhost addresses in alias
  509.      *     files, making it possible to share an alias
  510.      *     file for redirecting users around a network.
  511.      *
  512.      *     This moves intelligence out of resolve.c that
  513.      *     really belongs there.
  514.      */
  515.     char *temp_target;
  516.     char *temp_remainder;
  517.     char *temp_work_addr;
  518.     int form;
  519.  
  520.     temp_work_addr = COPY_STRING(addr->work_addr);
  521.     parseflags = addr->parseflags;
  522.     form = parse_address(temp_work_addr, &temp_target, &temp_remainder,
  523.                  &parseflags);
  524.  
  525.     switch (form) {
  526.     case FAIL:
  527.     case PARSE_ERROR:
  528.         xfree(temp_work_addr);
  529.         break;
  530.  
  531.     case LOCAL:
  532.         /*
  533.          * if the me_too flag is not set, then filter the sender
  534.          * from the output of directors.  A director can
  535.          * explicitly allow sender addresses to be produced by
  536.          * including the `sender_okay' attribute.  When expanding
  537.          * an address list for verification purposes, the sender
  538.          * may not be specified.  Watch out for this case.
  539.          */
  540.         xfree(temp_work_addr);
  541.         if (! (dp->flags & SENDER_OKAY) &&
  542.         ! me_too &&
  543.         sender &&
  544.         EQIC(sender, addr->work_addr))
  545.         {
  546.         DEBUG2(DBG_DIRECT_LO,
  547.                "    directed %s --> %s ... match sender, ignore\n",
  548.                addr->parent->remainder,
  549.                addr->work_addr);
  550.         return DROP_ADDRESS;
  551.         }
  552.         break;
  553.  
  554.     default:
  555.         if (islocalhost(temp_target) &&
  556.         EQIC(temp_remainder, addr->parent->remainder))
  557.         {
  558.         /*
  559.          * new addr same as input addr, send to
  560.          * the next director.  E.g., foo aliased
  561.          * to foo.
  562.          */
  563.         DEBUG2(DBG_DIRECT_LO,
  564.            "    directed %s --> %s ... match, pass to next director\n",
  565.                addr->parent->remainder,
  566.                addr->work_addr);
  567.         (void) strcpy(addr->work_addr, temp_remainder);
  568.         addr->remainder = addr->work_addr;
  569.         xfree(temp_work_addr);
  570.         return SEND_TO_NEXT;
  571.         }
  572.     }
  573.     }
  574.  
  575.     /* we have a new address to reparse */
  576.     DEBUG2(DBG_DIRECT_LO, "    directed %s --> %s\n",
  577.        addr->parent->remainder,
  578.        addr->in_addr);
  579.  
  580.     return ADDRESS_OKAY;
  581. }
  582.  
  583. /*
  584.  * finish_direct_special_form - direct a file, pipe or mailing list form addr
  585.  */
  586. /*ARGSUSED*/
  587. static void
  588. finish_direct_special_form(addr, dp, form, new, out, defer, fail, includes)
  589.     struct addr *addr;            /* addr structure to finish */
  590.     struct director *dp;        /* matching director */
  591.     enum local_form form;        /* local address form */
  592.     struct addr **new;            /* put new addrs to retry here */
  593.     struct addr **out;            /* resolved addrs */
  594.     struct addr **defer;        /* put config errors here */
  595.     struct addr **fail;            /* put failed addrs here */
  596.     struct addr **includes;        /* include file forms */
  597. {
  598.     /* save a pointer to the pipe transport */
  599.     static struct transport *pipe_transport = NULL;
  600.     /* save a pointer to the file transport */
  601.     static struct transport *file_transport = NULL;
  602.  
  603.     /*
  604.      * not a regular address, should we keep it or drop it?
  605.      *
  606.      * NOTE:  unsecure addresses are less secure than addresses which
  607.      *          are not secure.  Addresses which are not secure may have
  608.      *          accesses checked under the nobody uid/gid.  Unsecure
  609.      *          pipes, files and mailing lists are are always dropped.
  610.      */
  611.     /* only hash normal-form addresses */
  612.     addr->flags |= ADDR_DONTHASH;
  613.     if ((addr->flags & ADDR_UNSECURE) ||
  614.     ((addr->flags & ADDR_CAUTION) && ! (dp->flags & NOBODY_DIRECTOR)))
  615.     {
  616.     /*
  617.      * ERR_104 - security violation
  618.      *
  619.      * DESCRIPTION
  620.      *      A questionable address was supplied from a director
  621.      *      that is not allowed to supply a file command or
  622.      *      mailing list.
  623.      *
  624.      * ACTIONS
  625.      *      mail is sent to the address owner or to the
  626.      *      postmaster.
  627.      *
  628.      * RESOLUTION
  629.      *      The owner or postmaster should check the source source
  630.      *      of addresses against any file ownership restrictions
  631.      *      named in the director.
  632.      */
  633.     addr->error = note_error(ERR_NPOWNER|ERR_104,
  634.                  xprintf("director %s: security violation",
  635.                      dp->name));
  636.     addr->succ = *fail;
  637.     *fail = addr;
  638.     return;
  639.     }
  640.     if (addr->flags & ADDR_CAUTION) {
  641.     /* be cautious of addresses, but nobody is set */
  642.     if (operation_mode != VERIFY_ADDRS &&
  643.         operation_mode != TEST_MODE)
  644.     {
  645.         write_log(LOG_SYS,
  646.         "%s ... director %s: child of %s insecure, access as 'nobody'",
  647.               addr->in_addr,
  648.               dp->name,
  649.               addr->parent->in_addr);
  650.     }
  651.     addr->uid = nobody_uid;
  652.     addr->gid = nobody_gid;
  653.     }
  654.  
  655.     /* passed security checks, now what do we do? */
  656.     switch (form) {
  657.  
  658.     case PIPE_FORM:
  659.     /*
  660.      * pipe form, associate with the "pipe" transport
  661.      */
  662.     if (pipe_transport == NULL) {
  663.         pipe_transport = find_transport("pipe");
  664.         if (pipe_transport == NULL) {
  665.         /* configuration error, try again later */
  666.         /*
  667.          * ERR_105 - no pipe transport
  668.          *
  669.          * DESCRIPTION
  670.          *      There is no "pipe" transport in the
  671.          *      table of transports, and a shell command
  672.          *      address returned by a director.
  673.          *
  674.          * ACTIONS
  675.          *      Defer message as a configuration error.
  676.          *
  677.          * RESOLUTION
  678.          *      The postmaster should add a "pipe"
  679.          *      transport to the transport file.
  680.          */
  681.         addr->error = note_error(ERR_CONFERR|ERR_105,
  682.                      "no pipe transport");
  683.         addr->succ = *defer;
  684.         *defer = addr;
  685.         break;
  686.         }
  687.     }
  688.  
  689.     addr->transport = pipe_transport;
  690.     /* setup command as $user variable for transports */
  691.     addr->next_addr = COPY_STRING(addr->work_addr + 1);
  692.     DEBUG2(DBG_DIRECT_LO,
  693.            "    directed %s --> %s ... send to pipe transport\n",
  694.            addr->parent->remainder,
  695.            addr->in_addr);
  696.     /* addr finished link into the output queue */
  697.     addr->succ = *out;
  698.     *out = addr;
  699.     break;
  700.  
  701.     case FILE_FORM:
  702.     /*
  703.      * file form, associate with the "file" transport
  704.      */
  705.     if (file_transport == NULL) {
  706.         file_transport = find_transport("file");
  707.         if (file_transport == NULL) {
  708.         /* configuration error, must be fixed */
  709.         /*
  710.          * ERR_106 - no file transport
  711.          *
  712.          * DESCRIPTION
  713.          *      There is no "file" transport in the
  714.          *      table of transports, and a file form
  715.          *      address was returned by a director.
  716.          *
  717.          * ACTIONS
  718.          *      Defer message as a configuration error.
  719.          *
  720.          * RESOLUTION
  721.          *      The postmaster should add a "file"
  722.          *      transport to the transport file.
  723.          */
  724.         addr->error = note_error(ERR_CONFERR|ERR_106,
  725.                      "no file transport");
  726.         addr->succ = *defer;
  727.         *defer = addr;
  728.         break;
  729.         }
  730.     }
  731.     addr->transport = file_transport;
  732.  
  733.     /* setup file as $user variable for transports */
  734.     addr->next_addr = COPY_STRING(addr->work_addr);
  735.     DEBUG2(DBG_DIRECT_LO,
  736.            "    directed %s --> %s ... send to file transport\n",
  737.            addr->parent->remainder,
  738.            addr->in_addr);
  739.     /* addr finished link into the output queue */
  740.     addr->succ = *out;
  741.     *out = addr;
  742.     break;
  743.  
  744.     case INCLUDE_FORM:
  745.     /* mailing lists go back through all the directors */
  746.     DEBUG2(DBG_DIRECT_LO,
  747.            "    directed %s --> %s ... mailing list\n",
  748.            addr->parent->remainder,
  749.            addr->in_addr);
  750.     /* set local part to the mailing list address */
  751.     addr->remainder = addr->work_addr;
  752.     addr->succ = *includes;
  753.     *includes = addr;
  754.     break;
  755.     }
  756. }
  757.  
  758.  
  759. /*
  760.  * cache_director_data - cache in some generic director information
  761.  *
  762.  * perform once on each director to perform some lookup and expansion
  763.  * operations that would otherwise have to be performed each time these
  764.  * values are used.
  765.  */
  766. static void
  767. cache_director_data(dp)
  768.     register struct director *dp;
  769. {
  770.     if (dp->default_user) {
  771.     struct passwd *pw = getpwbyname(dp->default_user);
  772.     if (pw) {
  773.         dp->default_uid = pw->pw_uid;
  774.         dp->default_gid = pw->pw_gid;
  775.     } else {
  776.         dp->default_user = NULL;
  777.     }
  778.     }
  779.     if (dp->default_group) {
  780.     struct group *gr = getgrbyname(dp->default_group);
  781.     if (gr) {
  782.         dp->default_gid = gr->gr_gid;
  783.     } else {
  784.         dp->default_group = NULL;
  785.     }
  786.     }
  787.     if (dp->default_home) {
  788.     char *x_home =
  789.         expand_string(dp->default_home,
  790.               (struct addr *)NULL,
  791.               (char *)NULL,
  792.               (char *)NULL);
  793.     if (x_home && !EQ(x_home, dp->default_home)) {
  794.         dp->x_default_home = COPY_STRING(x_home);
  795.     } else {
  796.         dp->x_default_home = dp->default_home;
  797.     }
  798.     }
  799.     if (dp->set_user) {
  800.     struct passwd *pw = getpwbyname(dp->set_user);
  801.     if (pw) {
  802.         dp->set_uid = pw->pw_uid;
  803.         dp->set_gid = pw->pw_gid;
  804.     } else {
  805.         dp->set_user = NULL;
  806.     }
  807.     }
  808.     if (dp->set_group) {
  809.     struct group *gr = getgrbyname(dp->set_group);
  810.     if (gr) {
  811.         dp->set_gid = gr->gr_gid;
  812.     } else {
  813.         dp->set_group = NULL;
  814.     }
  815.     }
  816.     if (dp->set_home) {
  817.     char *x_home =
  818.         expand_string(dp->set_home,
  819.               (struct addr *)NULL,
  820.               (char *)NULL,
  821.               (char *)NULL);
  822.     if (x_home && !EQ(x_home, dp->set_home)) {
  823.         dp->x_set_home = COPY_STRING(x_home);
  824.     } else {
  825.         dp->x_set_home = dp->set_home;
  826.     }
  827.     }
  828. }
  829.  
  830. /*
  831.  * premunge_local_addrs - pre-routing munging on local addr structures
  832.  *
  833.  * Remove any extraneously set flags.
  834.  */
  835. static void
  836. premunge_local_addrs(list)
  837.     struct addr *list;            /* list of remote addrs to premunge */
  838. {
  839.     register struct addr *cur;        /* current address being processed */
  840.  
  841.     for (cur = list; cur; cur = cur->succ) {
  842.     cur->flags &= ~(ADDR_PUTDOT |
  843.             ADDR_MOVEDOT |
  844.             ADDR_ERROR |
  845.             ADDR_FINISHED |
  846.             ADDR_FULLMATCH |
  847.             ADDR_NOTUSER |
  848.             ADDR_ISUSER);
  849.     }
  850. }
  851.  
  852. /*
  853.  * addr_type - return the form of a local address string
  854.  *
  855.  * Determine if the address is a pipe, file, mailing list,
  856.  * or other.
  857.  */
  858. static enum local_form
  859. addr_type(s)
  860.     register char *s;
  861. {
  862.     /*
  863.      * file is one of:
  864.      *      "/string"
  865.      *      "\/string"
  866.      *      "~string"
  867.      *      "\~string"
  868.      *    /string
  869.      *      \/string
  870.      *      ~string
  871.      *      \~string
  872.      */
  873.     if (s[0] == '"' && ((s[1] == '/' || s[1] == '~') ||
  874.             (s[1] == '\\' && (s[2] == '/' || s[2] == '~'))))
  875.     {
  876.     /* file form, but only if the address is in local form */
  877.     register char *p = address_token(s);
  878.  
  879.     if (p && *p == '\0') {
  880.         /* address is in local form, strip work_addr inline */
  881.         (void) strip(s);
  882.         return FILE_FORM;
  883.     }
  884.     }
  885.     if (s[0] == '/' || s[0] == '~' ||
  886.     (s[0] == '\\' && (s[1] == '/' || s[1] == '~')))
  887.     {
  888.     /* filename not quoted, don't check for local form in this case */
  889.     (void) strip(s);
  890.     return FILE_FORM;
  891.     }
  892.  
  893.     /*
  894.      * pipe is one of:
  895.      *      "|shell-command"
  896.      *    "\|shell-command"
  897.      *    |shell-command
  898.      *      \|shell-command
  899.      */
  900.     if (s[0] == '"' && (s[1] == '|' || (s[1] == '\\' && s[2] == '|'))) {
  901.     /* pipe form, but only if the address is in local form */
  902.     char *p = address_token(s);
  903.  
  904.     if (p && *p == '\0') {
  905.         /* address is in local form, strip work_addr inline */
  906.         (void) strip(s);
  907.         return PIPE_FORM;
  908.     }
  909.     }
  910.     if (s[0] == '|' || (s[0] == '\\' && s[1] == '|')) {
  911.     /* shell command not quoted, don't check for local form in this case */
  912.     (void) strip(s);
  913.     return PIPE_FORM;
  914.     }
  915.  
  916.     /*
  917.      * mailing list is one of:
  918.      *      :include:anything
  919.      *    ":include:anything"
  920.      */
  921.     if (s[0] == '"' && s[1] == ':' &&
  922.     strncmpic(s + 2, "include:", sizeof("include:") - 1) == 0)
  923.     {
  924.     /* mailing list form, but only if the address is in local form */
  925.     char *p = address_token(s);
  926.  
  927.     if (p && *p == '\0') {
  928.         /* address is in local form, strip work_addr inline */
  929.         (void) strip(s);
  930.         return INCLUDE_FORM;
  931.     }
  932.     }
  933.  
  934.     if (s[0] == ':' && strncmpic(s+1, "include:", sizeof("include:")-1) == 0)
  935.     {
  936.     /* shell command not quoted, don't check for local form in this case */
  937.     return INCLUDE_FORM;
  938.     }
  939.  
  940.     return OTHER_FORM;
  941. }
  942.  
  943. /*
  944.  * director_user_info - fill an addr structure with user information
  945.  *
  946.  *
  947.  * if the remainder field if the addr structure matches a username,
  948.  * fill in fields which pertain to the user's passwd file entry.
  949.  */
  950. void
  951. director_user_info(addr)
  952.     struct addr *addr;            /* addr structure to check */
  953. {
  954.     struct passwd *pw;            /* passwd file entry for user */
  955.  
  956.     if (addr->flags & (ADDR_NOTUSER|ADDR_ISUSER)) {
  957.     /* a previous call to director_user_info() already took care of this */
  958.     return;
  959.     }
  960.  
  961.     /* get the passwd entry if one exists */
  962.     pw = getpwbyname(addr->remainder);
  963.     if (pw) {
  964.     /* passwd entry found */
  965.     addr->flags |= ADDR_ISUSER;
  966.     addr->uid = pw->pw_uid;
  967.     addr->gid = pw->pw_gid;
  968.     addr->home = COPY_STRING(pw->pw_dir);
  969.     return;
  970.     }
  971.  
  972.     /* no passwd entry found */
  973.     addr->flags |= ADDR_NOTUSER;
  974.     return;
  975. }
  976.  
  977.  
  978. /*
  979.  * find_director - given a director's name, return the director structure
  980.  *
  981.  * return NULL if no director of that name exists.
  982.  */
  983. struct director *
  984. find_director(name)
  985.     register char *name;        /* search key */
  986. {
  987.     register struct director *dp;    /* temp for stepping thru directors */
  988.  
  989.     /* loop through all the directors */
  990.     for (dp = directors; dp; dp = dp->succ) {
  991.     if (EQ(dp->name, name)) {
  992.         /* found the director in question */
  993.         return dp;
  994.     }
  995.     }
  996.  
  997.     return NULL;            /* director not found */
  998. }
  999.  
  1000. /*
  1001.  * find_direct_driver - given a driver's name, return the driver structure
  1002.  *
  1003.  * return NULL if driver does not exist.
  1004.  */
  1005. struct direct_driver *
  1006. find_direct_driver(name)
  1007.     register char *name;        /* search key */
  1008. {
  1009.     register struct direct_driver *ddp;    /* pointer to table of drivers */
  1010.  
  1011.     for (ddp = direct_drivers; ddp->name; ddp++) {
  1012.     if (EQ(ddp->name, name)) {
  1013.         return ddp;            /* found the driver */
  1014.     }
  1015.     }
  1016.  
  1017.     return NULL;            /* driver not found */
  1018. }
  1019.  
  1020.  
  1021. /*
  1022.  * read_director_file - read director file
  1023.  *
  1024.  * read the director file and build a director list describing the
  1025.  * entries.  Return an error message or NULL.
  1026.  */
  1027. char *
  1028. read_director_file()
  1029. {
  1030.     FILE *f;                /* open director file */
  1031.     char *error;            /* error from read_standard_file() */
  1032.     struct stat statbuf;
  1033.     static struct attr_table director_generic[] = {
  1034.     { "driver", t_string, NULL, NULL, OFFSET(director, driver) },
  1035.     { "caution", t_boolean, NULL, NULL, CAUTION_DIRECTOR },
  1036.     { "nobody", t_boolean, NULL, NULL, NOBODY_DIRECTOR },
  1037.     { "sender_okay", t_boolean, NULL, NULL, SENDER_OKAY },
  1038.     { "owner", t_string, NULL, NULL, OFFSET(director, owner) },
  1039.     { "default_user", t_string, NULL, NULL,
  1040.       OFFSET(director, default_user) },
  1041.     { "default_group", t_string, NULL, NULL,
  1042.       OFFSET(director, default_group) },
  1043.     { "default_home", t_string, NULL, NULL,
  1044.       OFFSET(director, default_home) },
  1045.     { "set_user", t_string, NULL, NULL, OFFSET(director, set_user) },
  1046.     { "set_group", t_string, NULL, NULL, OFFSET(director, set_group) },
  1047.     { "set_home", t_string, NULL, NULL, OFFSET(director, set_home) },
  1048.     };
  1049.     struct attr_table *end_director_generic = ENDTABLE(director_generic);
  1050.     static struct director director_template = {
  1051.     NULL,                /* name */
  1052.     "pathalias",            /* driver, a reasonable default */
  1053.     NULL,                /* succ will be assigned */
  1054.     NOBODY_DIRECTOR,        /* flags */
  1055.     NULL,                /* owner */
  1056.     NULL,                /* default_user */
  1057.     NULL,                /* default_group */
  1058.     NULL,                /* default_home */
  1059.     NULL,                /* set_user */
  1060.     NULL,                /* set_group */
  1061.     NULL,                /* set_home */
  1062.     NULL,                /* private */
  1063.     0,                /* cache - default_uid */
  1064.     0,                /* cache - default_gid */
  1065.     NULL,                /* cache - x_default_home */
  1066.     0,                /* cache - set_uid */
  1067.     0,                /* cache - set_gid */
  1068.     NULL,                /* cache - x_set_home */
  1069.     };
  1070.  
  1071.     /*
  1072.      * try to open directory file, stat file if possible
  1073.      */
  1074.     if (director_file == NULL || EQ(director_file, "-")) {
  1075.     return NULL;
  1076.     }
  1077.     f = fopen(director_file, "r");
  1078.     if (f == NULL) {
  1079.     if (require_configs) {
  1080.         return xprintf("%s:%s", director_file, strerrno());
  1081.     }
  1082.  
  1083.     add_config_stat(director_file, (struct stat *)NULL);
  1084.     return NULL;
  1085.     }
  1086.  
  1087.     (void)fstat(fileno(f), &statbuf);
  1088.     add_config_stat(director_file, &statbuf);
  1089.  
  1090.     /* call read_standard_file to do the real work */
  1091.     error = read_standard_file(f,
  1092.                    (char *)&director_template,
  1093.                    sizeof(struct director),
  1094.                    OFFSET(director, name),
  1095.                    OFFSET(director, flags),
  1096.                    OFFSET(director, succ),
  1097.                    director_generic,
  1098.                    end_director_generic,
  1099.                    director_driv_function,
  1100.                    (char **)&directors);
  1101.  
  1102.     /* finish up */
  1103.     (void) fclose(f);
  1104.  
  1105.     /* return any error message */
  1106.     if (error) {
  1107.     return xprintf("%s: %s", director_file, error);
  1108.     }
  1109.     return NULL;
  1110. }
  1111.  
  1112. static char *
  1113. director_driv_function(struct_p, driver_attrs)
  1114.     char *struct_p;            /* passed director structure */
  1115.     struct attribute *driver_attrs;    /* driver-specific attributes */
  1116. {
  1117.     struct director *dp = (struct director *)struct_p;
  1118.     struct direct_driver *drv;
  1119.  
  1120.     if (dp->driver == NULL) {
  1121.     return xprintf("director %s: no driver attribute", dp->name);
  1122.     }
  1123.     drv = find_direct_driver(dp->driver);
  1124.     if (drv == NULL) {
  1125.     return xprintf("director %s: unknown driver: %s",
  1126.                dp->name, dp->driver);
  1127.     }
  1128.     if (drv->builder) {
  1129.     return (*drv->builder)(dp, driver_attrs);
  1130.     }
  1131.  
  1132.     return NULL;
  1133. }
  1134.